
#ifndef GRAPHIC_OBJECT_H
#define GRAPHIC_OBJECT_H

// INCLUDES ********************************************************************

#include "Vector2D.h"

#include "Function.h"

#include "Logger.h"

#include "Tween.h"

#include <vector>

#include <utility>

// FORWARD DECLARATIONS ********************************************************

// *****************************************************************************

//! Drawable
//! 
//! Base class for all graphical objects

//! This will declare basic functionality used by objects such as sprite,
//! textlayers or tilemaps in common. 

// *****************************************************************************

namespace Meteor 
{
    class Drawable
    {
        public:
            typedef std::vector<std::pair<Tween*, Function*> > TweenContainerType;
        
            virtual ~Drawable(){};
        
            //! set the parent reference
            void SetParent( Drawable* const parent);
            
            const Drawable* const Parent() const;

            //! change this objects position, there is a default implementation
            //! for these functions that will probably fit all needs
            virtual void SetPosition( const float x, const float y);
            
            virtual void SetPosition( const Vector2D& newPosition);
        
            virtual const Vector2D& Position() const;
        
            virtual void MoveBy( const float x, const float y);
            
            virtual void MoveBy( const Vector2D& newPosition);
        
            //! will set and get this objects center point
            virtual void SetAnchorPoint( const float x, const float y);
            
            virtual void SetAnchorPoint( const Vector2D& newAnchor);
            
            virtual const Vector2D& AnchorPoint() const;
        

            virtual void SetScale( const float newScale);
            
            //! return the current scale
            virtual const float Scale() const;


            //! change this objects sizethere is a default implementation
            //! for these functions that will probably fit all needs
            virtual void SetSize( const float width, const float height);
            
            virtual void SetSize( const Vector2D& newSize);
            
            const Vector2D& Size() const;
            
            
            //! this object's rotation angle in degrees
            virtual void SetRotation( const float angle);
            
            virtual const float Rotation() const;
            
            
            //! this object's alpha value ( 0.0 to 1.0)
            virtual void SetAlpha( const float alpha);
        
            const float Alpha() const;
            
            
            //! objects with a higher z index will be drawn in front of
            //! those with a lower index
            virtual void SetIndexZ( const int index);
        
            const int IndexZ() const;
            
            
            //! set/get visibility
            virtual void SetVisible( const bool visibility);
            
            const bool Visible() const;
            
            //! update/draw cycles
            virtual void Update( const float deltaTime) = 0;
            
            virtual void Draw() const = 0;
        
            void ApplyTween( Tween* tween);
        
            void ApplyTween( Tween* tween, Function* callback);
        
            void ApplyTween( Tween* tween, const float delay, Function* callback);
    
        protected:
            Drawable();
        
            Drawable( const Drawable& drawable);
        
            const Drawable& operator=( const Drawable& rhs);
        
            explicit Drawable( const uint32_t zIndex);
        
            void UpdateTween( const TweenContainerType::iterator& animation, int* frame);
        
            //! reference to parent object
            Drawable* mParent;
        
            //! this objects position, set in pixel
            Vector2D mPosition;
            
            //! normalized value (0 to 1) defining the origin of the object
            Vector2D mAnchorPoint;
            
            //! this objects size, unit is pixel
            Vector2D mSize;
        
            //! translation according to mAnchorPoint
            Vector2D mTranslation;
        
            //! this objects scale
            float mScale;
            
             //! z index of this object
            uint32_t mIndexZ;
            
            //! the objects rotation in degrees
            float mRotation;
            
            //! the objects alpha
            float mAlpha;
        
            //! if invisible, draw will return immediately, thereby saving time
            bool mVisible;
        
            TweenContainerType mTweens;

    }; // end of class Drawable
    
} // end of namespace Meteor

#endif // GRAPHIC_OBJECT_H

